 # -*- coding: utf-8 -*-
"""
:Author: Fernando Pacheco <fernando.pacheco@ingesur.com.uy>
:Date: Sun, 14 Jun 2009 18:27:01 -0300
:copyright: Ingesur SRL
:license: GPL Version 2
:todo: Must complete missing functions
"""
from wellfunctions import *

class VWellNoPR(WellFunctions): 
    """
    Clase de base para el calculos de parametros de pozo en flujo no permanente

    Funciona para todos los acuiferos
    """
    def __init__(self):
            WellFunctions.__init__(self)
            
    def dropdown_unconfined_aquifer_tt(self, tt, Q,  r,  k, S, h0):
        """
        Calculo de descenso en acuiferos libres
    
        La decripcion larga
    
        :Parameters:
            Ho : float
                Nivel inicial de agua en el acuifero.
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            k : float
                Conductividad hidraulica en unidades homogeneas ( en este ejemplo en m/h).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso.
            S : float
                S coeficiente de almacenamiento.
            tt : array float
                valores de tiempo a los que se desea realizar el calculo
                
        """
        u = []
        s = []
        cont = 0
        for t in tt:
            u.append( r*r*S/(4.0*k*h0*t) )    
            ff = Q*self.Wu( u[cont] )[0] / ( 2.0*self.pi()*k )
            if ff > h0*h0:
                ## TODO: ver esto
                s.append( -10 )
            else:  
                s.append ( h0 - ( h0*h0 - ff ) ** (0.5) )
            cont = cont +1        
        return ( s )
        
    def dropdown_unconfined_aquifer(self, t, Q,  r,  k, S, h0):
        """
        Calculo de descenso en acuiferos libres
    
        La decripcion larga
    
        :Parameters:
            Ho : float
                Nivel inicial de agua en el acuifero.
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            k : float
                Conductividad hidraulica en unidades homogeneas ( en este ejemplo en m/h).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso.
            S : float
                S coeficiente de almacenamiento.
            t : float
                valor de tiempo al que se desea realizar el calculo
                
        """
        u = r*r*S/(4.0*k*h0*t) 
        ff = Q*self.Wu( u )[0] / ( 2.0*self.pi()*k )
        if ff > h0*h0:
            ## TODO: ver esto
            s = -10 
        else:  
            s= h0 - ( h0*h0 - ff ) ** (0.5) 
        return ( s )
        
    def dropdown_semiconfined_aquifer_tt(self, r, tt, Q, T, S, rdB, tipo = 'mem'):
        """
        Calculo de descaenso en acuiferos semiconfinados
    
        La decripcion larga
    
        :Parameters:
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            kp : float
                Conductividad hidraulica del acuitardo en unidades homogeneas ( en este ejemplo en m/h).
            bp : float
                Espesor del acuitardo en unidades homogeneas ( en este ejemplo en m).    
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            tt : array float
                valores de tiempo a los que se desea realizar el calculo    
        """    
        # B = self.sqrt( T/(kp/bp) )
        a = rdB
        u = []
        s = []
        cont = 0
        for t in tt:
            u.append( r*r*S/(4.0*T*t) )    
            s.append ( Q*self.Wua( u[cont], a, tipo )[0] / ( 4.0*self.pi()*T ) ) 
            cont = cont +1        
        return ( s )  
        
    def dropdown_semiconfined_aquifer(self, r, t, Q, T, S, B=None, kp=None, bp=None, tipo = 'mem'):
        """
        Calculo de descaenso en acuiferos semiconfinados
    
        La decripcion larga
    
        :Parameters:
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            B : float
                  Coeficiente de goteo.
            kp : float
                Conductividad hidraulica del acuitardo en unidades homogeneas ( en este ejemplo en m/h).
            bp : float
                Espesor del acuitardo en unidades homogeneas ( en este ejemplo en m).    
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            t : float
                valor de tiempo al que se desea realizar el calculo  
        :todo: Revisar por claridad. 
        """ 
        if not B:   
            if (kp and bp):
                B = self.sqrt( T/(kp/bp) )
            else:
                print "Problema"
                return (None)   
        a = r/B
        u = r*r*S/(4.0*T*t)
        tipo = 'notmem'    
        s = ( Q*self.Wua( u, a, tipo )[0]) / ( 4.0*self.pi()*T )      
        return ( s )    
    
    def dropdown_confined_aquifer_tt(self, tt, Q, r, T, S):
        """
        Calculo de descaenso en acuiferos confinados
    
        La decripcion larga
    
        :Parameters:
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            bp : float
                Espesor del acuitardo en unidades homogeneas ( en este ejemplo en m).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            Ri : float
                Radio de influencia.
            tt : array float
                valores de tiempo a los que se desea realizar el calculo
        """
        u = []
        s = []
        cont = 0
        ## print r, tt, Q, T, S
        for t in tt:
            u.append( r*r*S/( 4.0*T*t ) )    
            s.append ( Q*self.Wu( u[cont] )[0]/( 4.0*self.pi()*T ) ) 
            cont = cont +1    
        return ( s )
    
    def dropdown_confined_aquifer(self, t, Q, r, T, S):
        """
        Calculo de descaenso en acuiferos confinados
    
        La decripcion larga
    
        :Parameters:
            Q : float
                Caudal de extraccion (por ejemplo en m3/h).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            S : float
                Coeficiente de almacenamiento ( en este ejemplo en m).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            t : float
                valor de tiempo al que se desea realizar el calculo
        """
        u = r*r*S/( 4.0*T*t )
        s = Q*self.Wu( u )[0]/( 4.0*self.pi()*T )
        return ( s )
    
    def flow_rate_confined_aquifer(self, t, s, r, T,S):
        """
        Calculo de descaenso en acuiferos confinados
    
        La decripcion larga
    
        :Parameters:
            s : float
                Descenso ( en este ejemplo en m).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            S : float
                Coeficiente de almacenamiento ( en este ejemplo en m).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            t : float
                valor de tiempo al que se desea realizar el calculo
        """
        u = r*r*S/( 4.0*T*t )
        Q = (4*self.pi()*T*s)/ self.Wu(u)[0]
        return ( Q )
        
    ## :TODO: Faltan!!!! 
    def transmisivity_unconfined_aquifer(self):
        pass
        
    def transmisivity_semiconfined_aquifer(self):
        pass

    def transmisivity_confined_aquifer(self):
        pass

    def flow_rate_unconfined_aquifer(self, t, s,  r,  k, S, h0):
        """
        Calculo de descenso en acuiferos libres
    
        La decripcion larga
    
        :Parameters:
            s : float
                Descenso ( en este ejemplo en m).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            S : float
                Coeficiente de almacenamiento ( en este ejemplo en m).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            t : float
                valor de tiempo al que se desea realizar el calculo
            Ho : float
                  Altura inicial ( en este ejemplo en m).
        """
        h = (h0 - s)
        u = r*r*S/( 4.0*k*h0*t )
        Q = (2*self.pi()*k*(h0*h0 - h*h))/ self.Wu(u)[0]
        return ( Q )
        
    def flow_rate_semiconfined_aquifer(self, r, t, s, T, S, B=None, kp=None, bp=None, tipo = 'mem'):
        """
        Calculo de descenso en acuiferos semiconfinados
    
        La decripcion larga
    
        :Parameters:
            s : float
                Descenso ( en este ejemplo en m).
            T : float
                Transmisividad hidraulica en unidades homogeneas ( en este ejemplo en m2/h).
            S : float
                Coeficiente de almacenamiento ( en este ejemplo en m).
            r : float
                Distancia desde centro de bombeo donde se desea encontrar el descenso en unidades homogeneas ( en este ejemplo en m).
            t : float
                valor de tiempo al que se desea realizar el calculo
        """
        if not B:   
            if (kp and bp):
                B = self.sqrt( T/(kp/bp) )
            else:
                print "Problema"
                return (None)   
        a = r/B
        u = r*r*S/(4.0*T*t)
        tipo = 'notmem'
        Q = (2*self.pi()*T*s)/ self.Wua(u, a, tipo)[0]
        return ( Q )       
